﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using verk2013_project_group12.Filters;
using verk2013_project_group12.Models;
using WebMatrix.WebData;

namespace verk2013_project_group12.Controllers
{
    public class GamesController : Controller
    {
        //
        // GET: /Games/
        private IAppRepository _repository = null;

        public GamesController()
        {
            _repository = new AppRepository();
        }

        public GamesController(IAppRepository rep)
        {
            _repository = rep;
            // Used for unit testing
        }

        public ActionResult Index()
        { 
            GameRepository games = new GameRepository();
            var allGames = games.GetAllGames();
            return View(allGames);
            // Returns all users
        }

        [Authorize]
        public ActionResult TicTacToe(int? id)
        {
            if (id != null)
            {
                // First we check to see if the id is a number
                GameInstanceRepository games = new GameInstanceRepository();
                GameInstance theGame = games.GetInstanceById(id.Value);
                if (theGame != null)
                {
                    return View(theGame);
                    // Return the game interface if the id is valid
                }
                else
                { 
                    return View("404Error");
                }
            }
            else
            {
                return View("404Error");
            }
        }

        [Authorize]
        public ActionResult Yahtzee(int? id)
        {
            if (id != null)
            {
                // First we check to see if the id is a number
                GameInstanceRepository games = new GameInstanceRepository();
                GameInstance theGame = games.GetInstanceById(id.Value);
                if (theGame != null)
                {
                    return View(theGame);
                    // Return the game interface if the id is valid
                }
                else
                {
                    return View("404Error");
                }
            }
            else
            {
                return View("404Error");
            }
        }

        public ActionResult Lobby(int? id)
        { 
            if (id != null)
            { 
                // If the id is an integer
                var allGames = _repository.AllGames;

                var maxId = (from g in allGames
                             select g.ID).LastOrDefault();
                // Get the id of the newest game of the site
                if (id > maxId || id <= 0)
                {
                    return View("404Error");
                    // Return an errorpage if the game doesn't exist
                }
                else
                {
                    var gameById = from g in _repository.AllGameInstances
                                   where g.GameID == id && g.Running == false
                                   select g;
                    // gameById will be list of all instances in waiting position of one particular gametype.
                    return View(gameById);
                }

            }
            else
            {
               
                var allInstances = _repository.AllGameInstances;
                return View(allInstances);
                // If the parameder id is null the function will return list of all game instances
            }

        }


        [HttpGet]
        [Authorize]
        public ActionResult StartNewGame()
        {
            GameRepository games = new GameRepository();
            var allGames = games.GetAllGames();

            return View(allGames);
        }


        [HttpPost]
        [InitializeSimpleMembership]
        [Authorize]
        public ActionResult StartNewGame(FormCollection FormData)
        {

            var gameId = FormData["gameID"];
            //Getting gameId from FormCollection
            int theGameId = Convert.ToInt32(gameId);
            // Converting gameId from string to int.
            string numberOfPlayers = FormData[gameId];
            //G etting numberOfPlayers from FormCollection
            var number = (numberOfPlayers.Length) - 1;
            int numPlayer = Convert.ToInt32(numberOfPlayers[number]) - 48;
            // Converting string to int. -48 is there to change  from ascii to decimal.

            var memberId = WebSecurity.GetUserId(User.Identity.Name);
           
            
            UserRepository users = new UserRepository();
            GameRepository games = new GameRepository();
            GameInstance instance = new GameInstance();
            GameInstanceRepository instanceRep = new GameInstanceRepository();

            instance.GameID = theGameId;
            instance.LeaderUserId = memberId;
            instance.CurrentPlayers = 0;
            instance.PlayerCap = numPlayer;
            instanceRep.Add(instance);
            instanceRep.Save();
            //  Initialize the new instance and save it in the database.

            var nameOfTheGame = games.GetGameById(theGameId).Name;

            if(nameOfTheGame == "Tic-Tac-Toe")
            {
                nameOfTheGame = "TicTacToe";
            }
            
                return RedirectToAction(nameOfTheGame, new { id = instance.ID });
                //Redirect the user to new game he created.
            
            
        }

        [Authorize]
        public ActionResult Invite(int? id)
        { 
            //this function returns all invites.
            UserRepository rep = new UserRepository();
            var allUsers = rep.GetAllUsers();

            return View(allUsers);
        }
        
       
        [HttpPost]
        [InitializeSimpleMembership]
        [Authorize]
        public ActionResult Invite(int? id, FormCollection FormData)
        {
            // This function saves new invite to the database.
            GameInstanceRepository instanceRep = new GameInstanceRepository();
            GameInviteRepository inviteRep = new GameInviteRepository();
            GameRepository gameRep = new GameRepository();
            GameInvite invite = new GameInvite();

            var allGames = gameRep.GetAllGames();

            var gameInstance = instanceRep.GetInstanceById(id.Value);
            // gameInstance is the instance og the game that the user was invited to.
            

            var gameName = (from i in allGames
                            where i.ID == gameInstance.GameID 
                            select i).SingleOrDefault();
            // Finding the name of the game type
                            
            var invitedUserId = FormData["User"];
            int invitedUserIdInt = Convert.ToInt32(invitedUserId);
            var instanseid = id;
            var inviterName = User.Identity.Name;

            invite.InstanceID = id.Value;
            invite.InviterName = inviterName;
            invite.PlayerUserId = invitedUserIdInt;
            invite.GameName = gameName.Name;
            

            inviteRep.Add(invite);
            inviteRep.Save();
            //  Initialize the new invite and save it in the database.
            
            return RedirectToAction("Lobby");

        }

        [InitializeSimpleMembership]
        public ActionResult _ShowingInvite()
        {
            GameInstanceRepository instanceRep = new GameInstanceRepository();
            GameInviteRepository inviteRep = new GameInviteRepository();
            GameRepository gameRep = new GameRepository();
            GameInvite invite = new GameInvite();

            var allGames = gameRep.GetAllGames();
            var getAllInstances = instanceRep.GetAllInstances();
            var getAllInvites = inviteRep.GetAllInvites();
            List<GameInvite> invitesToDelete = new List<GameInvite>();
            // List of invites that will be deleted.

            foreach (var i in getAllInvites)
            {
                var temp = instanceRep.GetInstanceById(i.InstanceID);
                if (temp == null || temp.Running == true)
                {
                    invitesToDelete.Add(i);
                    /* If the the instance id in all invites are not in the database any more or is currently running
                   it will be added to the list */
                }

            }
            foreach (var i in invitesToDelete)
            {
                inviteRep.Remove(i);
                // All item in the list will be deleted.
            }
            inviteRep.Save();
            
            var allInvites = inviteRep.GetAllInvites();
            var userID = WebSecurity.GetUserId(User.Identity.Name);
            var userInvites = from i in allInvites
                              where i.PlayerUserId == userID
                              select i;
            // UserInvites will be list of all invite that the logged in user have.

            return PartialView(userInvites);
        }


        [HttpPost]
        public ActionResult joinInvite(int? id)
        {
            // This function will redirect the user to the game thad he was acceting to join.
            GameInviteRepository inviteRep = new GameInviteRepository();
            var theInvite = inviteRep.GetInviteByID(id.Value);

            string name = theInvite.GameName;

            if (name == "Tic-Tac-Toe")
            {
                name = "TicTacToe";
            }
            int instanceId = theInvite.InstanceID;

            inviteRep.Remove(theInvite);
            inviteRep.Save();
            // Removing the invite from the database.

            return RedirectToAction(name, new { id = instanceId });
        }


        [HttpPost]
        public ActionResult DeleteInvite(int? id)
        {
            // If the user will deny the invite than this function will remove the invite from the database.
            GameInviteRepository inviteRep = new GameInviteRepository();
            var theInvite = inviteRep.GetInviteByID(id.Value);

            inviteRep.Remove(theInvite);
            inviteRep.Save();

            return RedirectToAction("Lobby");
        }
        public ActionResult GameInfo(int? id)
        {
            // This function will return one particular game depending on the parameter id.
            GameRepository gameRep = new GameRepository();
            Game TheGame = gameRep.GetGameById(id.Value);
            var allGames = gameRep.GetAllGames();

            var maxId = (from g in allGames
                         select g.ID).LastOrDefault();
            // maxId is id of the latest game that was added.
            if (id > maxId || id <= 0)
            {
                return View("404Error");
                // Return an errorpage if the game doesn't exist
            }
              
            else
            {
                return View(TheGame);
            }


        }

        public ActionResult _GameFilter()
        {
            //This function returns a partial view.
            GameRepository gameRep = new GameRepository();
            var allGames = gameRep.GetAllGames();

            return PartialView(allGames);
            // Returns a list of all games.
        }

    }
}